<template>
  <div ref="tableContainer" class="table-container">
    <slot name="selectArea" />
    <ATable :columns="columns" :data-source="tableData" :pagination="false" :scroll="{ x: 'max-content', y: tableBodyHeight }" row-key="index" size="small">
      <template v-if="headSlots.length > 0" #headerCell="{ title, column }">
        <template v-for="(sname, index) in headSlots" :key="sname">
          <slot v-if="column.headerSlot === sname" :name="sname" v-bind="{ title, column, index }" />
        </template>
      </template>
      <template v-if="spinLoading" #bodyCell>
        <div class="skeleton-row animate-box" />
      </template>
      <template v-else #bodyCell="{ text, record, column, index }">
        <template v-for="sname in bodySlots" :key="sname">
          <slot v-if="column.bodySlot === sname" :name="sname" v-bind="{ text, record, column, index }" />
        </template>
      </template>
    </ATable>
    <div class="page-bar">
      <div>
        <slot name="pageBarLeft" />
      </div>
      <Pagination size="small" :total="page.total" :show-total="total => `共 ${page.total} 条`" :current="page.current" :page-size="page.size" :on-change="handleCurrentChange" :on-show-size-change="handleSizeChange" />
    </div>
  </div>
</template>

<script setup>
/**
 * --------------------------------------------------------------------
 * <<伯礼后台管理系统>>
 * ----------------------------------------------------------------------
 * Licensed 未经许可不能去掉去掉boli相关版权信息
 * ----------------------------------------------------------------------
 * Author: HuaBoli E-mail: <haboli1314@163.com>
 * ----------------------------------------------------------------------
 */
import { Table as ATable, Pagination } from 'ant-design-vue'
import { debounce } from 'lodash'

defineOptions({ name: 'BoliTabel' })

const { columns, skeletonRow, api, params, auto } = defineProps({
  api: {
    type: String,
    required: true,
  },
  params: {
    type: Object,
    default: () => {},
  },
  columns: {
    type: Array,
    required: true,
  },
  skeletonRow: {
    type: Number,
    default: 20,
  },
})

const spinLoading = ref(true) // 骨架屏loading
const tableData = ref([]) // 表格数据

// 获取 table-container 元素
const tableContainer = ref(null)

// 表格body高度
const tableBodyHeight = ref(300)

const headSlots = ref([]) // 头部插槽
const bodySlots = ref(columns.filter(col => col.bodySlot != null).map(col => col.bodySlot)) // 表格插槽

const page = reactive({
  current: 1,
  size: 20,
  total: 0,
})

// 更新表格高度
function updateTableHeight() {
  if (tableContainer.value) {
    tableBodyHeight.value = tableContainer.value.clientHeight - 82
    const tableBody = tableContainer.value.querySelectorAll('.ant-table-body')[0]
    if (tableBody) {
      tableBody.style.height = `${tableBodyHeight.value}px`
    }
  }
}

function getList() {
  spinLoading.value = true
  tableData.value = Array.from({ length: skeletonRow }, (_, index) => ({ id: index * 100, index }))
  httpRequest(api, { ...page, ...params }).then(({ records, totalRecords }) => {
    page.total = totalRecords
    tableData.value = records
    spinLoading.value = false
  })
}

const searchList = debounce(() => {
  page.current = 1
  page.total = 0
  getList()
}, 300)

function handleCurrentChange(current) {
  page.current = current
  getList()
}
function handleSizeChange(current, size) {
  page.size = size
}

function refresh() {
  page.current = 1
  page.total = 0
  getList()
}

// watch(() => params, searchList, { deep: true })
let resizeObserver = null
onMounted(() => {
  tableData.value = Array.from({ length: skeletonRow }, (_, index) => ({ id: index * 100, index }))
  getList()
  // 初始化高度
  updateTableHeight()

  // 创建ResizeObserver实例
  resizeObserver = new ResizeObserver(() => {
    updateTableHeight()
  })
  // 开始观察元素
  if (tableContainer.value) {
    resizeObserver.observe(tableContainer.value)
  }
  // 监听窗口变化（保留window.resize以确保兼容性）
  window.addEventListener('resize', updateTableHeight)
  // 组件卸载时清理
})
onUnmounted(() => {
  resizeObserver?.disconnect()
  window.removeEventListener('resize', updateTableHeight)
})

defineExpose({
  partRefresh: getList,
  refresh,
})
</script>

<style lang="less" scoped>
@keyframes skeleton-blink {
  0% {
    background-position: 100% 50%;
  }

  100% {
    background-position: 0 50%;
  }
}

@keyframes skeleton-blink {
  0% {
    background-position: 100% 50%;
  }

  100% {
    background-position: 0 50%;
  }
}

.table-container {
  position: relative;
  box-sizing: border-box;
  flex: 1;
  width: 100%;
  padding: 0 15px;
  overflow: hidden;
  background: #fff;

  .page-bar {
    position: absolute;
    bottom: 0;
    left: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    height: 45px;
    padding: 0 20px;
    background: #fff;
    border-top: 1px solid #e5e6eb;
  }

  &:deep(.ant-table-wrapper) {
    .ant-table {
      .ant-table-header {
        border-radius: 0 !important;
      }

      .ant-table-thead > tr > th {
        background: #f2f3f5;
      }

      .ant-table-body {
        &::-webkit-scrollbar {
          width: 4px;
          height: 8px;
        }
      }
    }

    .ant-table-container table > thead > tr:first-child > *:first-child {
      border-radius: 0 !important;
    }

    .ant-table.ant-table-small .ant-table-tbody > tr > td {
      padding: 7px 8px;
    }

    .ant-table-cell {
      font-size: 13px !important;
      font-weight: normal !important;
    }
  }

  .skeleton-row {
    width: 90%;
    height: 22px;
    background: rgb(244 245 247 / 100%);
  }

  .animate-box {
    flex-wrap: wrap;
    background-image: -webkit-gradient(
      linear,
      left top,
      right top,
      color-stop(25%, #f0f0f0),
      color-stop(37%, #e3e3e3),
      color-stop(63%, #f0f0f0)
    );
    background-image: -o-linear-gradient(left, #f0f0f0 25%, #e3e3e3 37%, #f0f0f0 63%);
    background-image: linear-gradient(90deg, #f0f0f0 25%, #e3e3e3 37%, #f0f0f0 63%);
    background-size: 400% 100%;
    animation: skeleton-blink 1.2s ease infinite;
  }
}
</style>
